// record clusters by each feature
// see Context-aware query suggestion by mining click-through and sesssion data, kdd08
#ifndef DIMARRAY_H_
#define DIMARRAY_H_
#include <vector>
#include <list>
#include "Cluster.h"

class DimArray{
  public:
    DimArray(int size){dim.resize(size);}

    void add(const Cluster* c) {
        const list<Node>& nodes = c->nodes();
        for(list<Node>::const_iterator it = nodes.begin();
            it != nodes.end();
            ++it) {
            dim[it->id].push_back(c);
        }
    }

    // combine c2 into c1
    // just change &c2 in list in every dim to c1
    void combine(const Cluster* c1, const Cluster* c2) {
        list<Node> nodes = c2->nodes();
        //filter node (feature) which are shared by c1 and c2
        for(list<Node>::iterator it = nodes.begin();
            it != nodes.end();) {
            if(c1->has_node(*it)) {
                // delete c2 from dimensions both in c1 and c2
                dim[it->id].remove(c2);
                
                it = nodes.erase(it);
            }
            else
                ++it;
        }
        
        // revise c2 to c1 for feature dimensions in c2 not in c1
        for(list<Node>::const_iterator it = nodes.begin();
            it != nodes.end();
            ++it) {
            list<const Cluster*>& li = dim[it->id];
            // replace c2 to c1
            for(list<const Cluster*>::iterator it = li.begin();
                it != li.end();
                ++it) {
                if(*it == c2)
                    *it = c1;
            }            
        }
        
    }
    // for test
    void print() {
        for(int i=0; i < dim.size(); ++i){
            printf("%d\t", i);
            for(list<const Cluster*>::iterator it = dim[i].begin();
                it != dim[i].end();
                ++it) {
                printf("%d ", (*it)->id());
            }
            printf("\n");
        }
    }
    
  private:
    //defined as pointer to a const variable, as we
    // has no need to revise cluster's content
    vector< list<const Cluster*> > dim;
};
#endif
